package com.gx.util.dbutil;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

/**
 * 采用Drurid作为数据源, 可注入  Apache Commons DBUtil
 * Created by gx on 2017/7/7.
 */
public class DBUtilsTemplate {
    private static final Logger log = LoggerFactory.getLogger(DBUtilsTemplate.class);

    private DBUtilsHelper dbUtilsHelper;
    private DataSource dataSource;

    //自选配置文件
    public DBUtilsTemplate(String fileName) {
        this.dbUtilsHelper = new DBUtilsHelper(fileName);
        this.dataSource = dbUtilsHelper.getDataSource();
    }

    public DBUtilsTemplate() {
        try {
            this.dataSource = DbPoolConnection.getInstance().getDataSource();
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }
    }


    /**
     * 查询返回 单个 javaBean
     *
     * @param sql
     * @param Class 返回 javabean  class
     * @param <T>
     * @return
     * @throws SQLException
     */
    public <T> T queryForBeanByOne(String sql, Class<T> Class) throws SQLException {
        T t = getQueryOne(sql, Class);
        return t;
    }

    public <T> T queryForBeanByOne(String sql, Class<T> Class, Object... objects) throws SQLException {
        T t = getQueryOne(sql, Class, objects);
        return t;
    }

    /**
     * 查询返回   javaBean list
     *
     * @param sql
     * @param Class
     * @param objects
     * @param <T>
     * @return
     * @throws SQLException
     */
    public <T> List<T> queryForBeanByList(String sql, Class<T> Class, Object... objects) throws SQLException {
        return getQueryList(sql, Class, objects);
    }
    public <T> List<T> queryForBeanByList(String sql, Class<T> Class) throws SQLException {
        return getQueryList(sql, Class, null);
    }

    /**
     * 查询单条数据  返回 Map
     *
     * @param sql
     * @return
     * @throws SQLException
     */
    public Map<String, Object> queryForMapByOne(String sql) throws SQLException {
        return dbUtilsHelper.getRunner().query(sql, new MapHandler());
    }

    public Map<String, Object> queryForMapByOne(String sql, Object... objects) throws SQLException {
        return dbUtilsHelper.getRunner().query(sql, new MapHandler(), objects);
    }

    /**
     * 查询多条数据返回 List<Map>
     *
     * @param sql
     * @param objects
     * @return
     * @throws SQLException
     */
    public List<Map<String, Object>> queryForMapByList(String sql, Object... objects) throws SQLException {
        return dbUtilsHelper.getRunner().query(sql, new MapListHandler(), objects);
    }

    public List<Map<String, Object>> queryForMapByList(String sql) throws SQLException {
        return dbUtilsHelper.getRunner().query(sql, new MapListHandler());
    }


    /**
     * 返回 一列的 list
     * @param sql
     * @param columnName
     * @return
     * @throws SQLException
     */
    public List<Object>  queryColumnList(String sql,String columnName) throws SQLException {
        return (List<Object>)dbUtilsHelper.getRunner().query(sql,new ColumnListHandler(columnName));
    }
    public List<Object>  queryColumnList(String sql,String columnName,Object...objects) throws SQLException {
        return (List<Object>)dbUtilsHelper.getRunner().query(sql,new ColumnListHandler(columnName),objects);
    }

    /**
     * 返回  以 columnName 为key  value 为 整行信息
     * @param sql
     * @param columnName
     * @return
     * @throws SQLException
     */
    public Map<Object, Map<String, Object>> queryKeyedHandler(String sql,String columnName ) throws SQLException{
        return (Map<Object, Map<String,Object>>) dbUtilsHelper.getRunner().
                query(sql, new KeyedHandler(columnName));
    }
    public Map<Object, Map<String, Object>> queryKeyedHandler(String sql,String columnName,Object...objects ) throws SQLException{
        return (Map<Object, Map<String,Object>>) dbUtilsHelper.getRunner().
                query(sql, new KeyedHandler(columnName),objects);
    }


    private <T> List<T> getQueryList(String sql, Class<T> t, Object... objects) throws SQLException {
        if (objects == null || objects.length == 0) {
            return (List<T>) dbUtilsHelper.getRunner().<T>query(sql, new BeanListHandler(t));
        }
        return (List<T>) dbUtilsHelper.getRunner().<T>query(sql, new BeanListHandler(t), objects);
    }

    private <T> T getQueryOne(String sql, Class<T> t) throws SQLException {
        return (T) dbUtilsHelper.getRunner().<T>query(sql, new BeanHandler(t));
    }

    private <T> T getQueryOne(String sql, Class<T> t, Object... objects) throws SQLException {
        return (T) dbUtilsHelper.getRunner().<T>query(sql, new BeanHandler(t), 3L, objects);
    }





    /**
     * 执行sql语句
     * <code>
     * executeUpdate("update user set username = 'kitty' where username = ?", "hello kitty");
     * </code>
     * @param sql   sql语句
     * @param param 参数
     * @return 受影响的行数
     */
    public int update(String sql, Object... param) throws SQLException {
        return dbUtilsHelper.getRunner().update(sql,param);
    }

    public int update(String sql) throws SQLException {
        return dbUtilsHelper.getRunner().update(sql);
    }

    /**
     * 批量插入
     * @param sql
     * @param params
     * @return
     * @throws SQLException
     */
    public int insertBath(String sql,Object[][] params) throws SQLException {
        return dbUtilsHelper.getRunner().update(sql);
    }


}
